<script lang="ts">
import { goto } from "$app/navigation"
import { page } from "$app/state"
import StepperCard from "$lib/components/ui/StepperCard.svelte"
import { EUDROP_ABI, EUDROP_CONTRACT_ADDRESS } from "$lib/constants/eudrop"
import { dashboard } from "$lib/dashboard/stores/user.svelte"
import { runPromiseExit$ } from "$lib/runtime"
import { Effect, Option } from "effect"
import { createPublicClient, http } from "viem"
import { mainnet } from "viem/chains"
import Step1 from "./step/Step1.svelte"
import Step2 from "./step/Step2.svelte"
import Step3 from "./step/Step3.svelte"
import Step4 from "./step/Step4.svelte"
import Step5 from "./step/Step5.svelte"
import Step6 from "./step/Step6.svelte"

let currentSlide = $state(0)
let stepperCardRef: StepperCard
let isInitialized = $state(false)
let isActive = $state<boolean>(false)

let claim = $derived(Option.flatMap(dashboard.airdrop, (store) => store.claim))
$effect(() => {
  if (currentSlide > 0 && Option.isNone(claim)) {
    goto("/eudrop/claim?step=1")
  }
})

let shouldCheckActive = $state(true)

runPromiseExit$(() =>
  shouldCheckActive && Option.isSome(claim)
    ? Effect.gen(function*() {
      const publicClient = createPublicClient({
        chain: mainnet,
        transport: http("https://rpc.1.ethereum.chain.kitchen"),
      })

      const active = yield* Effect.tryPromise({
        try: () =>
          publicClient.readContract({
            address: EUDROP_CONTRACT_ADDRESS,
            abi: EUDROP_ABI,
            functionName: "active",
            args: [],
          }),
        catch: () => false,
      })
      isActive = active
      shouldCheckActive = false
      return active
    }).pipe(
      Effect.catchAll(() =>
        Effect.gen(function*() {
          shouldCheckActive = false
          return yield* Effect.succeed(false)
        })
      ),
    )
    : Effect.void
)

$effect(() => {
  if (!isInitialized) {
    const step = page.url.searchParams.get("step")
    if (step) {
      const stepNumber = parseInt(step, 10)
      if (!isNaN(stepNumber) && stepNumber >= 1 && stepNumber <= 6) {
        // Auth guard: can't go beyond step 1 without authentication
        if (stepNumber > 1 && Option.isNone(dashboard.session)) {
          currentSlide = 0
        } // Claim guard: can't go beyond step 1 without claim data
        else if (stepNumber > 1 && Option.isNone(claim)) {
          currentSlide = 0
        } else {
          currentSlide = stepNumber - 1 // Convert to 0-based index
        }
      }
    }
    isInitialized = true
  }
})

// Update URL when slide changes (but not during initialization)
$effect(() => {
  if (isInitialized && currentSlide >= 0) {
    const currentStep = page.url.searchParams.get("step")
    const newStep = (currentSlide + 1).toString()

    // Only update if the URL step is different from current slide
    if (currentStep !== newStep) {
      const url = new URL(page.url)
      url.searchParams.set("step", newStep)
      goto(url.toString(), { replaceState: true, noScroll: true })
    }
  }
})

function goToNextSlide() {
  // Auth guard: can't proceed beyond step 1 without authentication
  if (currentSlide === 0 && Option.isNone(dashboard.session)) {
    return // Don't proceed if not authenticated
  }
  stepperCardRef.goToNextSlide()
}

function goToSlide(index: number) {
  // Auth guard: can't go beyond step 1 without authentication
  if (index > 0 && Option.isNone(dashboard.session)) {
    return // Don't proceed if not authenticated
  }
  stepperCardRef.goToSlide(index)
}

function goToPreviousSlide() {
  stepperCardRef.goToPreviousSlide()
}
</script>

<div class="flex justify-center items-center h-full w-full">
  <StepperCard
    bind:this={stepperCardRef}
    bind:currentSlide
    totalSlides={6}
    class="max-w-5xl md:h-auto"
  >
    {#snippet children(slideIndex)}
      <div class="flex flex-col gap-4 h-full w-full">
        {#if slideIndex === 0}
          <Step1
            onNext={goToNextSlide}
            {isActive}
          />
        {:else if slideIndex === 1}
          <Step2
            onNext={goToNextSlide}
            onBack={goToPreviousSlide}
          />
        {:else if slideIndex === 2}
          <Step3
            onNext={goToNextSlide}
            onBack={goToPreviousSlide}
          />
        {:else if slideIndex === 3}
          <Step4
            onNext={goToNextSlide}
            onBack={goToPreviousSlide}
          />
        {:else if slideIndex === 4}
          <Step5
            onNext={goToNextSlide}
            onBack={goToPreviousSlide}
          />
        {:else if slideIndex === 5}
          <Step6 onRestart={() => goToSlide(0)} />
        {/if}
      </div>
    {/snippet}
  </StepperCard>
</div>
